{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "35d84c42",
   "metadata": {},
   "source": [
    "# 函数\n",
    "* 1.函数的定义  \n",
    "> 1.数学： f(x) =ax+b  \n",
    "> 2.python: def fib(x)\n",
    "> 3. 编程思维 vs 数学思维 \n",
    ">>1.函数可以被定义名称,定义关键字 <font style=\"color:red\">**def**</font>  \n",
    ">>2.数学思维是写在同一行（定义函数 和运算公式），面向对象编程中 函数写多行，定义函数为单独一行  \n",
    ">>3.数学函数一般没有注释，而编程过程中，一般需要对函数进行注释描述（docstring，课本p151）  \n",
    ">>4.数学中:ax+b 是计算公式,而编程中,我们将函数的内容成为**函数**,函数体要有一定的**缩进**  \n",
    ">>5.数学函数执行,将参数代入公式,编程中函数执行,将参数代入函数体  \n",
    "\n",
    "* 2.函数的进阶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "78b27a0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 斐波那契数列： 0 1 1 2 3 5 8 13 21 34\n",
    "def fib(x):\n",
    "    \"\"\"列出指定x以内的斐波那契数列\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < x :\n",
    "        print(a,end= \" \")\n",
    "        a,b =b,a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "89da3104",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 "
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d8339638",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 实践: 写一个函数,这个函数可以打印\"你好,xxx同学\"\n",
    "def hello(name):\n",
    "    \"\"\"显示问候语\"\"\"\n",
    "    print(\"你好,%s同学\"%(name))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c4e8fb7c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好,lihua同学\n"
     ]
    }
   ],
   "source": [
    "hello(\"lihua\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e3828087",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():\n",
    "    \"\"\"显示问候语\"\"\"\n",
    "    print(\"hello,world\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "88c60ebb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,world\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "98c6e1b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 回顾与思考\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "354be130",
   "metadata": {},
   "outputs": [],
   "source": [
    "# sleeep()需要给定一个时间参数(int)参数\n",
    "time.sleep(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "5948f7f1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=2, tm_hour=10, tm_min=47, tm_sec=30, tm_wday=3, tm_yday=336, tm_isdst=0)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# localtime()不需要给定参数\n",
    "time.localtime()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ccef009",
   "metadata": {},
   "source": [
    "> 3. 函数的优势\n",
    ">> 1. 可以重复使用相同的功能,避免重复造轮子  \n",
    ">> 2. 使用者可以不了解函数本身,只需要清楚如何使用即可  \n",
    ">> 3. 使用/调用方便,只需要%s"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a2e1388",
   "metadata": {},
   "source": [
    "# 函数的参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18d791e6",
   "metadata": {},
   "source": [
    "> 1.形式参数  (形参)\n",
    ">> A. 在**定义**函数的时候定义的参数  \n",
    ">> B.形式参数不占用内存   \n",
    "\n",
    "> 2.实际参数(实参)  \n",
    ">>A.在**调用**函数的时候定义的参数  \n",
    ">>B.调用函数时,形式参数分配空间,传递实际参数,执行函数内容  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33b454ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 课本函数实践案例\n",
    "def search4vowels(word):\n",
    "    \"\"\"显示文本中出现的元音字母有哪些\"\"\"\n",
    "    vowels = set(\"aeiou\")\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "175eb62c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'i', 'o', 'e', 'a', 'u'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"hbshwggaihuwbeoou\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0e8ae27",
   "metadata": {},
   "source": [
    "* 在多个参数\n",
    "\n",
    "> 1.位置参数 \n",
    ">>1. 在形式参数的定义中,有一定的先后顺序  \n",
    ">>2. 在调用函数时,要考虑形参的先后顺序  \n",
    ">>3. 调用函数时,不仅要考虑参数位置,还需要考虑形式参数的个数  \n",
    "\n",
    "> 2.关键字参数  \n",
    ">>1.在调用函数时,关键字参数可以不考虑形式参数的位置   \n",
    "> 3.默认参数\n",
    ">>1. 调用参数时,可以省略传递的参数信息\n",
    ">>2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "9af2cc51",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(pet_name,animal_type):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is\" + pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "9fa117ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "My dog's name is豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "996d6c90",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a豆豆.\n",
      "My 豆豆's name isDog.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "49af1ea0",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 1 required positional argument: 'animal_type'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-39-7b9959e7e395>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"豆豆\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() missing 1 required positional argument: 'animal_type'"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "2b0bb8d0",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-40-4397d3a8a91b>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-40-4397d3a8a91b>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    describe_pet(animal_type=\"cat\",pet_name\"微积分\")\u001b[0m\n\u001b[1;37m                                           ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "describe_pet(animal_type=\"cat\",pet_name\"微积分\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "5c5bc118",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(pet_name,animal_type):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is\" + pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "f60b792c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have acat.\n",
      "My cat's name is豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"cat\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0eb1ba7",
   "metadata": {},
   "source": [
    "* 参数注意事项实践  \n",
    ">1.位置参数和关键字参数同时使用  \n",
    ">>1.positional argument followers keyword argument (关键字参数<font style=\"color:red\">均</font>应该放在位置参数之后)\n",
    ">>2.只要满足1的条件,剩余的关键字参数(多个)不考虑先后顺序\n",
    "\n",
    ">2.非默认参数和默认参数同时使用(定义函数)\n",
    ">>1.non-default argument followers default argument ("
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "56187b72",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,y,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "dc8344c0",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-46-42371a9326bd>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-46-42371a9326bd>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    test(5,y=3,2)\u001b[0m\n\u001b[1;37m               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "# 实践1:\n",
    "test(5,y=3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "832558c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "3\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 实践2:\n",
    "test(5,3,z=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6dddc617",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实践3\n",
    "test()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
